import { useCallback, useSyncExternalStore } from 'react'

function subscribe(callback: () => void) {
  window.addEventListener('storage', (_) => {
    callback()
  })
  return () => window.removeEventListener('storage', callback)
}

/**
 *
 * @param key
 * @param defaultValue
 */
export function useStorage<T>(key: string, defaultValue?: T): [T | null, (value: T) => void] {
  const getSnapshot = () => {
    return (sessionStorage.getItem(key) ? sessionStorage.getItem(key) : null) ?? JSON.stringify(defaultValue || '')
  }
  const setStorage = useCallback((value: T) => {
    sessionStorage.setItem(key, JSON.stringify(value))
    window.dispatchEvent(new StorageEvent('storage'))
  }, [])

  const res = useSyncExternalStore(subscribe, getSnapshot)
  const storageRes: T | null = res ? JSON.parse(res) : null

  return [storageRes, setStorage]
}
